package config

import (
	"common/logs"
	"github.com/go-redis/redis/v8"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"log"
	"os"
)

// AppConf 全局配置变量
var AppConf = InitConfig()

func InitConfig() *Config {
	conf := &Config{viper: viper.New()}

	// 设置配置文件类型
	conf.viper.SetConfigType("yaml")
	zap.L().Info("[读取本地配置文件]")
	worDir, _ := os.Getwd()
	// 设置文件名称
	conf.viper.SetConfigName("config")
	// docker linux 环境下读取配置
	conf.viper.SetConfigType("yaml")
	conf.viper.AddConfigPath("./project")
	conf.viper.AddConfigPath(worDir + "/config")
	err := conf.viper.ReadInConfig()
	if err != nil {
		log.Fatal(err)
	}

	//// 先从nacos读取配置，如果读取不到，在本地读取
	//nacosClient := InitNacosClient()
	//
	//// 读取string类型的配置文件
	//configYaml, err := nacosClient.confClient.GetConfig(vo.ConfigParam{
	//	DataId: nacosClient.NacosConf.DataId,
	//	Group:  nacosClient.NacosConf.Group,
	//})
	//if err != nil {
	//	log.Fatal(err)
	//}
	//
	//// 监听配置变化
	//err2 := nacosClient.confClient.ListenConfig(vo.ConfigParam{
	//	DataId: nacosClient.NacosConf.DataId,
	//	Group:  nacosClient.NacosConf.Group,
	//	OnChange: func(namespace, group, dataId, data string) {
	//		// 重新读取nacos的最新文件
	//		log.Printf("load nacos config changed %s \n", data)
	//		err := conf.viper.ReadConfig(bytes.NewBuffer([]byte(data)))
	//		if err != nil {
	//			log.Printf("load nacos config changed err: %s \n", err.Error())
	//		}
	//
	//		// 所有的配置应该重新读取
	//		conf.ReLoadAllConfig()
	//	},
	//})
	//
	//if err2 != nil {
	//	log.Fatal(err2)
	//}
	//
	//if configYaml != "" {
	//	err = conf.viper.ReadConfig(bytes.NewBuffer([]byte(configYaml)))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	log.Printf("load nacos config %s \n", configYaml)
	//} else {
	//	// 本地读取
	//	zap.L().Info("[读取本地配置文件]")
	//	worDir, _ := os.Getwd()
	//	// 设置文件名称
	//	conf.viper.SetConfigName("config")
	//	// docker linux 环境下读取配置
	//	conf.viper.SetConfigType("yaml")
	//	conf.viper.AddConfigPath("./project")
	//	conf.viper.AddConfigPath(worDir + "/config")
	//	err = conf.viper.ReadInConfig()
	//	if err != nil {
	//		log.Fatalln(err)
	//	}
	//	if err != nil {
	//		log.Fatal(err)
	//		return nil
	//	}
	//}

	// 配置载入conf==> AppConf
	conf.ReLoadAllConfig()
	return conf
}

// ReLoadAllConfig 读取最新配置
func (c *Config) ReLoadAllConfig() {
	c.InitServerConfig()
	c.InitZapLog()
	c.InitGrpcConfig()
	c.InitEtcdConfig()
	//c.InitMysqlConfig()
	//c.InitJwtConfig()
	//c.InitDbConfig()
	//c.InitKafkaConfig()
	//c.InitJaegerConfig()

	// 重新创建相关客户端
	//c.ReConnRedis()
	//c.ReConnMysql()
}

// InitServerConfig Server配置读取
func (c *Config) InitServerConfig() {
	sc := &ServerConf{
		Name: c.viper.GetString("server.name"),
		Addr: c.viper.GetString("server.addr"),
	}
	c.Sc = sc
}

// InitZapLog Zaplog读取配置文件并初始化
func (c *Config) InitZapLog() {
	// 从配置中读取日志配置，初始化日志
	lg := &logs.LogConfig{
		DebugFileName: c.viper.GetString("zap.debugFileName"),
		InfoFileName:  c.viper.GetString("zap.infoFileName"),
		WarnFileName:  c.viper.GetString("zap.warnFileName"),
		MaxSize:       c.viper.GetInt("zap.maxSize"),
		MaxAge:        c.viper.GetInt("zap.maxAge"),
		MaxBackups:    c.viper.GetInt("zap.maxBackups"),
	}

	if err := logs.InitLogger(lg); err != nil {
		log.Fatal(err)
	}
}

// InitGrpcConfig grpc服务器初始化
func (c *Config) InitGrpcConfig() {
	gc := &GrpcConf{
		Addr:     c.viper.GetString("grpc.addr"),
		Name:     c.viper.GetString("grpc.name"),
		EtcdAddr: c.viper.GetString("grpc.etcd_addr"),
		Version:  c.viper.GetString("grpc.version"),
		Weight:   c.viper.GetString("grpc.weight"),
	}
	c.Gc = gc
}

// InitEtcdConfig Etcd 配置读取
func (c *Config) InitEtcdConfig() {
	ec := &EtcdConf{}
	var addrs []string
	err := c.viper.UnmarshalKey("etcd.addrs", &addrs)
	if err != nil {
		log.Fatal(err)
	}
	ec.Addrs = addrs
	c.Ec = ec
}

// InitMysqlConfig mysql初始化配置功能
func (c *Config) InitMysqlConfig() {
	mc := &MysqlConf{
		Username: c.viper.GetString("mysql.username"),
		Password: c.viper.GetString("mysql.password"),
		Host:     c.viper.GetString("mysql.host"),
		Port:     c.viper.GetInt32("mysql.port"),
		Db:       c.viper.GetString("mysql.db"),
	}
	c.Mc = mc
}

// InitJwtConfig Jwt配置读取
func (c *Config) InitJwtConfig() {
	jc := &JwtConf{
		AccessExp:     c.viper.GetInt64("jwt.accessExp"),
		RefreshExp:    c.viper.GetInt64("jwt.refreshExp"),
		AccessSecret:  c.viper.GetString("jwt.accessSecret"),
		RefreshSecret: c.viper.GetString("jwt.refreshSecret"),
	}
	c.Jc = jc
}

// InitDbConfig 初始化DB主从配置
func (c *Config) InitDbConfig() {
	mc := &DbConf{}
	mc.Separation = c.viper.GetBool("db.separation")
	var slaves []MysqlConf
	err := c.viper.UnmarshalKey("db.slave", &slaves)
	if err != nil {
		panic(err)
	}
	master := MysqlConf{
		Username: c.viper.GetString("db.master.username"),
		Password: c.viper.GetString("db.master.password"),
		Host:     c.viper.GetString("db.master.host"),
		Port:     c.viper.GetInt32("db.master.port"),
		Db:       c.viper.GetString("db.master.db"),
	}
	mc.Master = master
	mc.Slave = slaves
	c.Dc = mc
}

// InitKafkaConfig kafka配置
func (c *Config) InitKafkaConfig() {
	kc := &KafkaConf{}
	var addr []string
	err := c.viper.UnmarshalKey("kafka.addr", &addr)
	if err != nil {
		log.Fatal(err)
	}

	kc.Addr = addr
	kc.Topic = c.viper.GetString("kdfka.topic")
	kc.Group = c.viper.GetString("jaeger.endpoints")
	c.Kc = kc
}

// InitJaegerConfig jacger配置信息
func (c *Config) InitJaegerConfig() {
	jac := &JaegerConf{
		Endpoints: c.viper.GetString("jaeger.endpoints"),
	}
	c.Jaeger = jac
}

// InitRedisOptions Redis配置初始化
func (c *Config) InitRedisOptions() *redis.Options {
	return &redis.Options{
		Addr:     c.viper.GetString("redis.host") + ":" + c.viper.GetString("redis.port"),
		Password: c.viper.GetString("redis.password"),
		DB:       c.viper.GetInt("redis.db"),
	}
}
